home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Moscow ML 1.31 / source code / mosml / src / compiler / Lexer.lex < prev    next >
Encoding:
Text File  |  1996-07-03  |  10.9 KB  |  422 lines  |  [TEXT/R*ch]

  1. {
  2. open Fnlib Memory Config Mixture Const Parser;
  3.  
  4. (* For Quote/Antiquote --- object language embedding. *)
  5.  
  6. val quotation = ref false;
  7.  
  8. datatype lexingMode =
  9.     NORMALlm
  10.   | QUOTElm
  11.   | ANTIQUOTElm
  12. ;
  13.  
  14. val lexingMode = ref NORMALlm;
  15.  
  16. val parCount = Stack.new() : int Stack.t;
  17.  
  18. fun resetLexerState() =
  19. (
  20.   lexingMode := NORMALlm;
  21.   Stack.clear parCount
  22. );
  23.  
  24. (* For nesting comments *)
  25.  
  26. val comment_depth = ref 0;
  27.  
  28. (* The table of keywords *)
  29.  
  30. val keyword_table = (Hasht.new 53 : (string,token) Hasht.t);
  31.  
  32. val () =
  33. List.app (fn (str,tok) => Hasht.insert keyword_table str tok)
  34. [
  35.   ("abstype",    ABSTYPE),
  36.   ("and",        AND),
  37.   ("andalso",    ANDALSO),
  38.   ("as",         AS),
  39.   ("case",       CASE),
  40.   ("datatype",   DATATYPE),
  41.   ("do",         DO),
  42.   ("else",       ELSE),
  43.   ("eqtype",     EQTYPE),
  44.   ("end",        END),
  45.   ("exception",  EXCEPTION),
  46.   ("fn",         FN),
  47.   ("fun",        FUN),
  48.   ("handle",     HANDLE),
  49.   ("if",         IF),
  50.   ("in",         IN),
  51.   ("infix",      INFIX),
  52.   ("infixr",     INFIXR),
  53.   ("let",        LET),
  54.   ("local",      LOCAL),
  55.   ("nonfix",     NONFIX),
  56.   ("of",         OF),
  57.   ("op",         OP),
  58.   ("open",       OPEN),
  59.   ("orelse",     ORELSE),
  60.   ("prim_eqtype",  PRIM_EQTYPE),
  61.   ("prim_EQtype",  PRIM_REFTYPE),
  62.   ("prim_type",    PRIM_TYPE),
  63.   ("prim_val",     PRIM_VAL),
  64.   ("raise",      RAISE),
  65.   ("rec",        REC),
  66.   ("then",       THEN),
  67.   ("type",       TYPE),
  68.   ("val",        VAL),
  69.   ("while",      WHILE),
  70.   ("with",       WITH),
  71.   ("withtype",   WITHTYPE),
  72.   ("#",          HASH),
  73.   ("->",         ARROW),
  74.   ("|",          BAR),
  75.   (":",          COLON),
  76.   ("=>",         DARROW),
  77.   ("=",          EQUALS),
  78.   ("*",          STAR)
  79. ];
  80.  
  81. fun mkKeyword lexbuf =
  82.   let val s = getLexeme lexbuf in
  83.     Hasht.find keyword_table s
  84.     handle Subscript => ID s
  85.   end
  86. ;
  87.  
  88. val savedLexemeStart = ref 0;
  89.  
  90. val initial_string_buffer = CharArray.array(256, #"\000");
  91. val string_buff = ref initial_string_buffer;
  92. val string_index = ref 0;
  93.  
  94. fun reset_string_buffer() =
  95. (
  96.   string_buff := initial_string_buffer;
  97.   string_index := 0;
  98.   ()
  99. );
  100.  
  101. fun store_string_char c =
  102.   let open CharArray
  103.       val len = length (!string_buff)
  104.   in
  105.     if !string_index >= len then
  106.       let val new_buff = array(len * 2, #"\000") in
  107.         copy
  108.           { src = !string_buff, si = 0, dst = new_buff, di = 0, len = len };
  109.         string_buff := new_buff
  110.       end
  111.     else ();
  112.     update(!string_buff, !string_index, c);
  113.     incr string_index
  114.   end;
  115.  
  116. fun get_stored_string() =
  117.   let open CharArray
  118.       val s = extract(!string_buff, 0, SOME (!string_index))
  119.   in
  120.     string_buff := initial_string_buffer;
  121.     s
  122.   end;
  123.  
  124. fun splitQualId s =
  125.   let open CharVector
  126.       val len' = size s - 1
  127.       fun parse n =
  128.         if n >= len' then
  129.           ("", s)
  130.         else if sub(s, n) = #"." then
  131.           ( normalizedUnitName (extract(s, 0, SOME n)),
  132.             extract(s, n + 1, SOME(len' - n)) )
  133.         else
  134.           parse (n+1)
  135.   in parse 0 end;
  136.  
  137. fun mkQualId lexbuf =
  138.   let val (qual, id) = splitQualId(getLexeme lexbuf) in
  139.     if id = "*" then
  140.       QUAL_STAR { qual=qual, id=id }
  141.     else
  142.       QUAL_ID   { qual=qual, id=id }
  143.   end
  144. ;
  145.  
  146. fun charCodeOfDecimal lexbuf i =
  147.   100 * (Char.ord(getLexemeChar lexbuf i) - 48) +
  148.    10 * (Char.ord(getLexemeChar lexbuf (i+1)) - 48) +
  149.         (Char.ord(getLexemeChar lexbuf (i+2)) - 48)
  150. ;
  151.  
  152. fun lexError msg lexbuf =
  153. (
  154.   resetLexerState();
  155.   raise LexicalError(msg, getLexemeStart lexbuf, getLexemeEnd lexbuf)
  156. );
  157.  
  158. fun constTooLarge msg lexbuf =
  159. (
  160.   resetLexerState();
  161.   lexError (msg ^ " constant is too large") lexbuf
  162. );
  163.  
  164. fun notTerminated msg lexbuf =
  165. (
  166.   resetLexerState();
  167.   raise LexicalError (msg ^ " not terminated",
  168.                       !savedLexemeStart, getLexemeEnd lexbuf)
  169. );
  170.  
  171. fun skipString msg skip lexbuf =
  172.   let
  173.     val pos1 = getLexemeStart lexbuf
  174.     val pos2 = getLexemeEnd lexbuf
  175.   in
  176.     skip lexbuf;
  177.     resetLexerState();
  178.     raise (LexicalError(msg, pos1, pos2))
  179.   end
  180. ;
  181.  
  182. fun scanString scan lexbuf =
  183. (
  184.   reset_string_buffer();
  185.   savedLexemeStart := getLexemeStart lexbuf;
  186.   scan lexbuf;
  187.   setLexStartPos lexbuf (!savedLexemeStart - getLexAbsPos lexbuf)
  188. );
  189.  
  190. }
  191.  
  192. rule Token = parse
  193.     [^ `\000`-`\255`]
  194.       { lexError "this will be never called!" lexbuf }
  195.   | ""
  196.       { case !lexingMode of
  197.             NORMALlm =>
  198.               TokenN lexbuf
  199.           | QUOTElm =>
  200.               (scanString Quotation lexbuf;
  201.                case !lexingMode of
  202.                    NORMALlm =>
  203.                      QUOTER (get_stored_string())
  204.                  | ANTIQUOTElm =>
  205.                      QUOTEM (get_stored_string())
  206.                  | QUOTElm =>
  207.                      fatalError "Token")
  208.           | ANTIQUOTElm =>
  209.               AntiQuotation lexbuf
  210.       }
  211.  
  212. and TokenN = parse
  213.     [` ` `\n` `\r` `\t`]  { TokenN lexbuf }
  214.   | "(*"
  215.       { savedLexemeStart := getLexemeStart lexbuf;
  216.         comment_depth := 1; Comment lexbuf; TokenN lexbuf
  217.       }
  218.   | "*)"
  219.       { lexError "unmatched comment bracket" lexbuf }
  220.   | "'" [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]+
  221.                 { TYVAR   (getLexeme lexbuf) }
  222.   | "0"         { ZDIGIT 0 }
  223.   | [`1`-`9`]   { NZDIGIT   (sml_int_of_string(getLexeme lexbuf)) }
  224.   | "0" [`0`-`9`]+
  225.                 { ZPOSINT2  (sml_int_of_string(getLexeme lexbuf))
  226.                   handle Fail _ => constTooLarge "integer" lexbuf
  227.                 }
  228.   | [`1`-`9`] [`0`-`9`]+
  229.                 { NZPOSINT2 (sml_int_of_string(getLexeme lexbuf))
  230.                   handle Fail _ => constTooLarge "integer" lexbuf
  231.                 }
  232.   | "~" [`0`-`9`]+
  233.                 { NEGINT    (sml_int_of_string(getLexeme lexbuf))
  234.                   handle Fail _ => constTooLarge "integer" lexbuf
  235.                 }
  236.   | "~"? [`0`-`9`]+ (`.` [`0`-`9`]+)? (`E` `~`? [`0`-`9`]+)?
  237.                 { REAL (sml_float_of_string (getLexeme lexbuf))
  238.                   handle Fail _ => constTooLarge "real" lexbuf
  239.                 }
  240.   | "\""
  241.       { scanString String lexbuf;
  242.         STRING (get_stored_string())
  243.       }
  244.   | "#\""
  245.       { scanString String lexbuf;
  246.         let val s = get_stored_string() in
  247.           if size s <> 1 then
  248.             lexError "ill-formed character constant" lexbuf
  249.           else ();
  250.           CHAR (CharVector.sub(s, 0))
  251.         end }
  252.   | "_"         { UNDERBAR }
  253.   | ","         { COMMA }
  254.   | "..."       { DOTDOTDOT }
  255.   | "{"         { LBRACE }
  256.   | "}"         { RBRACE }
  257.   | "["         { LBRACKET }
  258.   | "#["        { HASHLBRACKET }
  259.   | "]"         { RBRACKET }
  260.   | "("
  261.      { if not(Stack.null parCount) then
  262.          Stack.push (Stack.pop parCount + 1) parCount
  263.        else ();
  264.        LPAREN
  265.      }
  266.   | ")"
  267.       { if not(Stack.null parCount) then
  268.           let val count = Stack.pop parCount - 1 in
  269.             if count = 0 then
  270.               (lexingMode := QUOTElm; Token lexbuf)
  271.             else
  272.               (Stack.push count parCount; RPAREN)
  273.           end
  274.         else
  275.           RPAREN
  276.       }
  277.   | ";"         { SEMICOLON }
  278.   | (eof | `\^Z`) { EOF }
  279.   | ""          { if !quotation then TokenIdQ lexbuf else TokenId lexbuf }
  280.  
  281. and TokenId = parse
  282.     ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  283.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  284.        `~` `\`` `^` `|` `*`]+ )
  285.       { mkKeyword lexbuf }
  286.   | ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  287.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  288.        `~` `\`` `^` `|` `*`]+ )
  289.     "."
  290.     ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  291.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  292.        `~` `\`` `^` `|` `*`]+ )
  293.       { mkQualId lexbuf }
  294.   | _
  295.       { lexError "ill-formed token" lexbuf }
  296.  
  297. and TokenIdQ = parse
  298.     ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  299.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  300.        `~` `^` `|` `*`]+ )
  301.       { mkKeyword lexbuf }
  302.   | ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  303.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  304.        `~` `^` `|` `*`]+ )
  305.     "."
  306.     ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  307.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  308.        `~` `^` `|` `*`]+ )
  309.       { mkQualId lexbuf }
  310.   | "`"
  311.       { lexingMode := QUOTElm; QUOTEL }
  312.   | _
  313.       { lexError "ill-formed token" lexbuf }
  314.  
  315. and Comment = parse
  316.     "(*"
  317.       { (incr comment_depth; Comment lexbuf) }
  318.   | "*)"
  319.       { (decr comment_depth;
  320.          if !comment_depth > 0 then Comment lexbuf else ()) }
  321.   | (eof | `\^Z`)
  322.       { notTerminated "comment" lexbuf }
  323.   | _
  324.       { Comment lexbuf }
  325.  
  326. and String = parse
  327.     `"`
  328.       { () }
  329.   | `\\` [`\\` `"` `n` `t`]
  330.       { store_string_char(char_for_backslash(getLexemeChar lexbuf 1));
  331.         String lexbuf }
  332.   | `\\` [` ` `\t` `\n` `\r`]+ `\\`
  333.       { String lexbuf }
  334.   | `\\` `^` [`@`-`_`]
  335.       { store_string_char(
  336.           Char.chr(Char.ord(getLexemeChar lexbuf 2) - 64));
  337.         String lexbuf }
  338.   | `\\` [`0`-`9`] [`0`-`9`] [`0`-`9`]
  339.       { let val code = charCodeOfDecimal lexbuf 1 in
  340.           if code >= 256 then
  341.             skipString "character code is too large" SkipString lexbuf
  342.           else ();
  343.           store_string_char(Char.chr code);
  344.           String lexbuf
  345.         end }
  346.   | `\\`
  347.       { skipString "ill-formed escape sequence" SkipString lexbuf }
  348.   | (eof | `\^Z`)
  349.       { notTerminated "string" lexbuf }
  350.   | [`\^A`-`\^Z` `\127` `\255`]
  351.       { skipString "invalid character in string" SkipString lexbuf }
  352.   | _
  353.       { (store_string_char(getLexemeChar lexbuf 0);
  354.          String lexbuf) }
  355.  
  356. and SkipString = parse
  357.     `"`
  358.       { () }
  359.   | `\\` [`\\` `"` `n` `t`]
  360.       { SkipString lexbuf }
  361.   | `\\` [` ` `\t` `\n` `\r`]+ `\\`
  362.       { SkipString lexbuf }
  363.   | (eof | `\^Z`)
  364.       { notTerminated "string" lexbuf }
  365.   | _
  366.       { SkipString lexbuf }
  367.  
  368. and Quotation = parse
  369.     "`"
  370.       { lexingMode := NORMALlm }
  371.   | `^`
  372.       { lexingMode := ANTIQUOTElm }
  373.   | `\r`
  374.       { Quotation lexbuf }
  375.   | [`\t` `\n`]
  376.       { (store_string_char(getLexemeChar lexbuf 0);
  377.          Quotation lexbuf) }
  378.   | (eof | `\^Z`)
  379.       { lexingMode := NORMALlm;
  380.         notTerminated "quotation" lexbuf
  381.       }
  382.   | [`\^A`-`\^Z` `\127` `\255`]
  383.       { skipString "invalid character in quotation" SkipQuotation lexbuf }
  384.   | _
  385.       { (store_string_char(getLexemeChar lexbuf 0);
  386.          Quotation lexbuf) }
  387.  
  388. and SkipQuotation = parse
  389.     "`"
  390.       { lexingMode := NORMALlm }
  391.   | (eof | `\^Z`)
  392.       { lexingMode := NORMALlm;
  393.         notTerminated "quotation" lexbuf
  394.       }
  395.   | _
  396.       { SkipQuotation lexbuf }
  397.  
  398. and AntiQuotation = parse
  399.     ( [`A`-`Z` `a`-`z`] [ `A`-`Z` `a`-`z` `0`-`9` `_` `'`]*
  400.     | [`!` `%` `&` `$` `#` `+` `-` `/` `:` `<` `=` `>` `?` `@` `\\`
  401.        `~` `|` `*`]+ )
  402.       { lexingMode := QUOTElm;
  403.         mkKeyword lexbuf
  404.       }
  405.   | "("
  406.       { Stack.push 1 parCount; lexingMode := NORMALlm;
  407.         TokenN lexbuf
  408.       }
  409.   | "`"
  410.       { lexingMode := NORMALlm;
  411.         lexError "antiquotation is missing" lexbuf
  412.       }
  413.   | (eof | `\^Z`)
  414.       { lexingMode := NORMALlm;
  415.         notTerminated "antiquotation" lexbuf
  416.       }
  417.   | _
  418.       { lexingMode := QUOTElm;
  419.         lexError "ill-formed antiquotation" lexbuf
  420.       }
  421. ;
  422.